package com.sk.netty.server;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;
import javafx.concurrent.Worker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

@Sharable//标识一个channelHandler可以被多个channel安全的共享
public class EchoServerHandlerIn extends ChannelInboundHandlerAdapter{
    Logger logger = LoggerFactory.getLogger(EchoServerHandlerIn.class);

    //当一个新链接被建立当时候，该方法会被调用
    @Override public void channelActive(ChannelHandlerContext ctx) throws Exception {
        logger.info("已激活。新的链接来啦！注意查收。Client {} connected", ctx.channel().remoteAddress());
        super.channelActive(ctx);
    }

    @Override public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        logger.info("channel 未注册");
        super.channelUnregistered(ctx);
    }

    @Override public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        logger.info("channel 已注册");
        super.channelRegistered(ctx);
    }

    @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        logger.info("channel 未激活");
        super.channelInactive(ctx);
    }

    @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf)msg;
        String message = byteBuf.toString(CharsetUtil.UTF_8);
        logger.info("server received message = {}",message);

        byteBuf.readChar();
        ((ByteBuf) msg).writeBytes(",you is boy".getBytes("utf-8"));
        logger.info("server received message = {}",byteBuf.toString(CharsetUtil.UTF_8));

        ((ByteBuf) msg).setBytes(byteBuf.writerIndex()," ok".getBytes("utf-8"));
        logger.info("server received message = {}",byteBuf.toString(CharsetUtil.UTF_8));

        ByteBuf b1 = ((ByteBuf) msg).copy(0,byteBuf.writerIndex()+3);
        logger.info("server received message = {}",b1.toString(CharsetUtil.UTF_8));

        ByteBuf b2 = ((ByteBuf) msg).slice(0,byteBuf.writerIndex()+3);
        logger.info("server received message = {}",b2.toString(CharsetUtil.UTF_8));

        ((ByteBuf) msg).setBytes(byteBuf.writerIndex()-2,"ok".getBytes("utf-8"));
        logger.info("server received message = {}",byteBuf.toString(CharsetUtil.UTF_8));

        ctx.write(Unpooled.copiedBuffer(byteBuf));

        boolean b = ReferenceCountUtil.release(msg);
        logger.info("server msg = " + b);
        //ctx.write(Unpooled.copiedBuffer(message,CharsetUtil.UTF_8);//将消息回写给发送者，但不冲刷出站消息。
    }

    @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        //将未决消息冲刷到远程节点，并关闭该Channel。
        System.out.println("刷新啦");
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(new ChannelFutureListener() {
            @Override public void operationComplete(ChannelFuture channelFuture) throws Exception {
                if(channelFuture.isSuccess()){
                    channelFuture.channel().close();
                }else {
                    channelFuture.cause().printStackTrace();
                    channelFuture.channel().close();
                }
            }
        });
    }

    @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error("异常信息:{}",cause.getStackTrace());//打印异常日志信息
        ctx.close();//关闭Channel
    }
}
